unit ProdutoDM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ZDataset, ZSqlUpdate, ZSequence, MainDM, DB, QueryConditions;

type

  { TProdutoData }

  TProdutoData = class(TMainDataModule)
    ConsomeDataDatasource: TDatasource;
    ConsomeDataZQuerydata: TDateField;
    ConsomeDataZQuerydesc_produto: TStringField;
    ConsomeDataZQueryid_produto: TLargeintField;
    ConsomeDataZQueryid_saida: TLargeintField;
    ConsomeDataZQueryid_saida_produto: TLargeintField;
    ConsomeDataZQueryid_usuario: TLargeintField;
    ConsomeDataZQueryquantidade: TFloatField;
    ConsomeDataZQueryquantidade_saiu: TFloatField;
    ConsomeDataZQuerysigla_unidade: TStringField;
    ConsomeDataZQuerytotal: TFloatField;
    ConsomeDataZQueryvalor: TFloatField;
    ConsomeProDatasource: TDatasource;
    ConsomeProZQuerydesc_produto: TStringField;
    ConsomeProZQueryid_produto: TLargeintField;
    ConsomeProZQueryquantidade_saiu: TFloatField;
    ConsomeProZQuerysigla_unidade: TStringField;
    ConsomeProZQuerytotal: TFloatField;
    MinimoDatasource: TDatasource;
    HProdutoDatasource: TDatasource;
    HProdutoZQueryatualizar: TStringField;
    HProdutoZQuerydata_entrada: TDateTimeField;
    HProdutoZQuerydesc_produto: TStringField;
    HProdutoZQueryid_entrada: TLargeintField;
    HProdutoZQueryid_entrada_produto: TLargeintField;
    HProdutoZQueryid_produto: TLargeintField;
    HProdutoZQueryquantidade: TFloatField;
    HProdutoZQueryvalor: TFloatField;
    MinimoZQuerycodigo_barra: TStringField;
    MinimoZQuerycusto: TFloatField;
    MinimoZQuerydesconto: TFloatField;
    MinimoZQuerydesc_produto: TStringField;
    MinimoZQuerydesc_produto_completa: TStringField;
    MinimoZQueryid_grupo: TLargeintField;
    MinimoZQueryid_marca: TLargeintField;
    MinimoZQueryid_produto: TLargeintField;
    MinimoZQueryminimoTotal: TFloatField;
    MinimoZQuerynota: TStringField;
    MinimoZQueryqtdeAbaixo: TFloatField;
    MinimoZQueryquantidade: TFloatField;
    MinimoZQueryquantidade_minima: TFloatField;
    MinimoZQuerysigla_unidade: TStringField;
    MinimoZQueryvalor: TFloatField;
    ProdutoDatasource: TDatasource;
    ProdutoZQuerycodigo_barra: TStringField;
    ProdutoZQuerycusto: TFloatField;
    ProdutoZQuerydesconto: TFloatField;
    ProdutoZQuerydesc_grupo: TStringField;
    ProdutoZQuerydesc_marca: TStringField;
    ProdutoZQuerydesc_produto: TStringField;
    ProdutoZQuerydesc_produto_completa: TStringField;
    ProdutoZQueryid_grupo: TLargeintField;
    ProdutoZQueryid_marca: TLargeintField;
    ProdutoZQueryid_produto: TLargeintField;
    ProdutoZQuerynota: TStringField;
    ProdutoZQueryquantidade: TFloatField;
    ProdutoZQueryquantidade_minima: TFloatField;
    ProdutoZQuerysigla_unidade: TStringField;
    ProdutoZQuerytotComDesc: TFloatField;
    ProdutoZQueryvalor: TFloatField;
    ProdutoZSequence: TZSequence;
    ProdutoZUpdate: TZUpdateSQL;
    ProdutoZQuery: TZQuery;
    AuxiliarZQuery: TZQuery;
    HProdutoZQuery: TZQuery;
    ConsomeDataZQuery: TZQuery;
    ConsomeProZQuery: TZQuery;
    MinimoZQuery: TZQuery;
    procedure ConsomeDataZQueryCalcFields(DataSet: TDataSet);
    procedure DataModuleCreate(Sender: TObject);
    procedure MinimoZQueryCalcFields(DataSet: TDataSet);
    /// Abre o DataSet
    procedure OpenDataSet(); override;
    /// Fecha o DataSet
    procedure CloseDataSet(); override;
    procedure ProdutoZQueryCalcFields(DataSet: TDataSet);
    /// Realiza busca
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); override;
    procedure BuscaCustoProdutos(IDProduto: string);
    function AlteraCodigoBarra(): string;
    procedure BuscaProdutoGrupo(IDGrupo: string; tipo: string);
    function BuscaProdutoCodigoBarra(CodigoBarra: string): boolean;
    procedure BuscaProdutoMarca(IDMarca: string; tipo: string);
    function BuscaProdutoDescProduto(DescProduto: string; tipo: string): boolean;
    function GeraCodigoBarra(): string;
    function VerificaCodigoBarra(Codigo: string): boolean;
    procedure BuscaQuantidadeMinima(tipo: string);
    procedure BuscaQuantidadeMinimaGrupo(tipo: string; Grupo: string);
    procedure BuscaDataConsumo(DataInicio: string; DataFim: string);
    procedure BuscaDataConsumoProduto(DataInicio: string; DataFim: string;
      Produto: string);
  end;

var
  ProdutoData: TProdutoData;

implementation

uses ConnectionDM;

{ TProdutoData }

procedure TProdutoData.DataModuleCreate(Sender: TObject);
begin
  MainDataSet := ProdutoZQuery;
end;

procedure TProdutoData.MinimoZQueryCalcFields(DataSet: TDataSet);
var
  v: real;
begin
  v := MinimoZQueryquantidade.AsFloat - MinimoZQueryquantidade_minima.AsFloat;
  if v < 0 then begin
    MinimoZQueryqtdeAbaixo.Value :=
      (MinimoZQueryquantidade_minima.AsFloat - MinimoZQueryquantidade.AsFloat);
    MinimoZQueryminimoTotal.Value :=
      (MinimoZQueryqtdeAbaixo.AsFloat * MinimoZQuerycusto.AsFloat);
  end;
end;

procedure TProdutoData.ConsomeDataZQueryCalcFields(DataSet: TDataSet);
begin
  ConsomeDataZQuerytotal.Value :=
    (ConsomeDataZQueryquantidade_saiu.AsFloat * ConsomeDataZQueryvalor.AsFloat);
end;

procedure TProdutoData.OpenDataSet;
begin
  ConnectionData.EmptyQuery(ProdutoZQuery, 'produto');
end;

procedure TProdutoData.CloseDataSet;
begin
  ProdutoZQuery.Close();
  HProdutoZQuery.Close();
end;

procedure TProdutoData.ProdutoZQueryCalcFields(DataSet: TDataSet);
begin
  ProdutoZQuerytotComDesc.Value :=
    (ProdutoZQueryvalor.AsFloat - StrToFloatDef(ProdutoZQuerydesconto.AsString, 0));
end;

procedure TProdutoData.Search(Condicoes: TQueryConditions; Tabela: string);
begin
  ConnectionData.OpenQueryConditions(ProdutoZQuery, Tabela, Condicoes);
end;

procedure TProdutoData.BuscaCustoProdutos(IDProduto: string);
begin
  with HProdutoZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select p.desc_produto, ei.* from produto as p, entrada_produto as ei where ei.id_produto =:id_produto');
    ParamByName('id_produto').AsString := IDProduto;
    Open();
  end;
end;

function TProdutoData.AlteraCodigoBarra(): string;
begin
  ProdutoZQuery.Post();
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('UPDATE produto');
    SQL.Add('SET codigo_barra=:id_produto');
    SQL.Add('WHERE id_produto=:id_produto');
    ParamByName('id_produto').AsString :=
      ProdutoZQuery.FieldByName('id_produto').AsString;
    ExecSQL();
  end;
  ProdutoZQuery.Open();
  Result := ProdutoZQuery.FieldByName('id_produto').AsString;
end;

procedure TProdutoData.BuscaProdutoGrupo(IDGrupo: string; tipo: string);
var
  Planilha: string;
begin
  if tipo = 'E' then begin
    with ProdutoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE id_grupo =:id_grupo');
      ParamByName('id_grupo').AsString := IDGrupo;
      Open();
    end;
  end else begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE id_grupo =:id_grupo');
      ParamByName('id_grupo').AsString := IDGrupo;
      Open();
    end;
  end;
end;


function TProdutoData.BuscaProdutoCodigoBarra(CodigoBarra: string): boolean;
begin
  with ProdutoZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from produto');
    SQL.Add('WHERE codigo_barra =:codigo_barra');
    ParamByName('codigo_barra').AsString := CodigoBarra;
    Open();
    if RecordCount > 0 then begin
      Result := True;
    end else begin
      Result := False;
    end;
  end;
end;

procedure TProdutoData.BuscaProdutoMarca(IDMarca: string; tipo: string);
begin
  if tipo = 'E' then begin
    with ProdutoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE id_marca =:id_marca');
      ParamByName('id_marca').AsString := IDMarca;
      Open();
    end;
  end else begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE id_marca =:id_marca');
      ParamByName('id_marca').AsString := IDMarca;
      Open();
    end;
  end;
end;

function TProdutoData.BuscaProdutoDescProduto(DescProduto: string;
  tipo: string): boolean;
begin
  if tipo = 'E' then begin
    with ProdutoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE desc_produto like :desc_produto');
      ParamByName('desc_produto').AsString := '%' + DescProduto + '%';
      Open();
      if RecordCount > 0 then begin
        Result := True;
      end else begin
        Result := False;
      end;
    end;
  end else begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      SQL.Add('WHERE desc_produto like :desc_produto');
      ParamByName('desc_produto').AsString := '%' + DescProduto + '%';
      Open();
      if RecordCount > 0 then begin
        Result := True;
      end else begin
        Result := False;
      end;
    end;
  end;
end;

function TProdutoData.GeraCodigoBarra(): string;
var
  I, aleatorio: integer;
  codigo: string;
  continua: boolean;
begin
  continua := True;
  while continua = True do begin
    for I := 0 to 12 do begin
      aleatorio := Random(9);
      codigo := codigo + IntToStr(aleatorio);
    end;
    if VerificaCodigoBarra(codigo) then begin
      continua := False;
    end;
  end;
  Result := codigo;
end;

function TProdutoData.VerificaCodigoBarra(Codigo: string): boolean;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * from produto');
    SQL.Add('WHERE codigo_barra =:codigo');
    ParamByName('codigo').AsString := Codigo;
    Open();
    if RecordCount > 0 then begin
      Result := False;
    end else begin
      Result := True;
    end;
  end;
end;

procedure TProdutoData.BuscaQuantidadeMinima(tipo: string);
begin
  if tipo = 'Todos' then begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto');
      Open();
    end;
  end else if tipo = 'Igual' then begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto where quantidade = quantidade_minima');
      Open();
    end;
  end else begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto where quantidade < quantidade_minima');
      Open();
    end;
  end;
end;

procedure TProdutoData.BuscaQuantidadeMinimaGrupo(tipo: string; Grupo: string);
begin
  if tipo = 'Todos' then begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto where id_grupo=:grupo');
      ParamByName('grupo').AsString := Grupo;
      Open();
    end;
  end else if tipo = 'Igual' then begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto where quantidade = quantidade_minima and id_grupo=:grupo');
      ParamByName('grupo').AsString := Grupo;
      Open();
    end;
  end else begin
    with MinimoZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('SELECT * from produto where quantidade < quantidade_minima and id_grupo=:grupo');
      ParamByName('grupo').AsString := Grupo;
      Open();
    end;
  end;
end;

procedure TProdutoData.BuscaDataConsumo(DataInicio: string; DataFim: string);
begin
  with ConsomeDataZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select p.desc_produto,p.sigla_unidade, sp.*, s.data, s.id_usuario');
    SQL.Add('FROM produto as p, saida_produto as sp, saida as s');
    SQL.Add('WHERE p.id_produto=sp.id_produto AND sp.id_saida=s.id_saida');
    SQL.Add('AND (s.data between :data_inicio AND :data_fim)');
    ParamByName('data_inicio').AsString := DataInicio;
    ParamByName('data_fim').AsString := DataFim;
    Open();
  end;
  with ConsomeProZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select p.id_produto,p.desc_produto,');
    SQL.Add(
      'p.sigla_unidade,sum(quantidade_saiu) as quantidade_saiu, sum(quantidade_saiu*sp.valor) as total');
    SQL.Add('FROM produto as p, saida_produto as sp,saida as s');
    SQL.Add('WHERE p.id_produto=sp.id_produto AND sp.id_saida=s.id_saida');
    SQL.Add('AND (s.data BETWEEN :data_inicio AND :data_fim)');
    SQL.Add('group by desc_produto, p.sigla_unidade, p.id_produto');
    ParamByName('data_inicio').AsString := DataInicio;
    ParamByName('data_fim').AsString := DataFim;
    Open();
  end;
end;

procedure TProdutoData.BuscaDataConsumoProduto(DataInicio: string;
  DataFim: string; Produto: string);
begin
  with ConsomeDataZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select p.desc_produto,p.sigla_unidade, sp.*, s.data, s.id_usuario');
    SQL.Add('FROM produto as p, saida_produto as sp, saida as s');
    SQL.Add('WHERE p.id_produto=sp.id_produto AND sp.id_saida=s.id_saida');
    SQL.Add('AND p.desc_produto=:desc_produto');
    SQL.Add('AND (s.data between :data_inicio AND :data_fim)');
    ParamByName('data_inicio').AsString := DataInicio;
    ParamByName('data_fim').AsString := DataFim;
    ParamByName('desc_produto').AsString := '%' + Produto + '%';
    Open();
  end;
  with ConsomeProZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select p.id_produto,p.desc_produto,');
    SQL.Add(
      'p.sigla_unidade,sum(quantidade_saiu) as quantidade_saiu, sum(quantidade_saiu*sp.valor) as total');
    SQL.Add('FROM produto as p, saida_produto as sp,saida as s');
    SQL.Add('WHERE p.id_produto=sp.id_produto AND sp.id_saida=s.id_saida');
    SQL.Add('AND p.desc_produto=:desc_produto');
    SQL.Add('AND (s.data BETWEEN :data_inicio AND :data_fim)');
    SQL.Add('group by desc_produto, p.sigla_unidade, p.id_produto');
    ParamByName('data_inicio').AsString := DataInicio;
    ParamByName('data_fim').AsString := DataFim;
    ParamByName('desc_produto').AsString := '%' + Produto + '%';
    Open();
  end;
end;

initialization
  {$I produtodm.lrs}

end.
